classdef Filter_dev < Processor_dev
  % SeaBird's low-pass filter function
  % Derived from Processor_dev
  % Constructor signature: filt = Filter_dev(conn), arg. optional
  %
  % Author: David Goldsmith, Wash. State Dept. of Ecology, dgol461@ecy.wa.gov
  % Release date: 9/15/2011

    properties
      % inherited from Processor_dev
      % inData;
      % castDT;
      % scanRate;
      % ParamID;
      % ParamDesc;
      % SBEprec;
      % EquipID;
        DBdata;
        outData;
        param; % Physical parameter(s) to Filter
        A;     % Intermediate parameters to be reused
    end
    
    methods
        function filt = Filter_dev(conn) % Constructor
            filt = filt@Processor_dev();
            if nargin
                filt.doSubstantive(conn)
            end
        end
        
        function doSubstantive(obj, conn)
            global instHeaderData mSB
            if nargin-1, obj.getDBdata(conn, 'Filter'); end
            if ~isempty(obj.DBdata)
                for field=fieldnames(obj.DBdata)'
                    field = field{:};
                    rhTS0  = 2 * obj.DBdata.(field){1} * instHeaderData.scanRate;
                    obj.A = 1 / (1 + rhTS0);
                    appPar = regexp(obj.DBdata.(field){2}, '_', 'split');
                    q = query_dev(conn, struct('cols', {{'MatlabProcessingID'}},...
                                               'tbls', {{'Parameter'}}));
                    if mSB, q.setPropVals('cols', 'SBEPrecision', 1); end
                    where = ['ParameterID IN (' sprintf('%s, ', appPar{1:end-1})];
                    where = [where appPar{end} ')'];
                    q.setPropVals('where', {where})
                    q.submitStatement
                    appPar = q.result;
                    if mSB, appPar = appPar(:,1); end
                    if mSB, SBEprec = q.result(:,2); 
                    else obj.SBEprec = 0; end
                    for n=1:numel(appPar)
                        obj.param = appPar{n};
                        if mSB, obj.SBEprec = SBEprec{n}; end
                        obj.outData.(obj.param) = [];
                        obj.mainFormula
                    end
                end
            end
        end
        
        function mainFormula(obj)
            global P T C H X F U R dov S DOS

            x = eval([obj.param '.outData']);

            if obj.SBEprec % Unless we're in "mSB mode," this should be 0
                if ismember(obj.param, {'U', 'R'})
                    pow = round2(log10(abs(x)), 1, 'fix') + 1 ...
                                 - eval([obj.param '.SBEprec']);
                    x = round2(x, 10.^pow);
                else
                    x = round2(x, eval([obj.param '.SBEprec']));
                end
            end
            
            forward = obj.filter(x);
            bakward = flipud(obj.filter(flipud(forward)));

            if obj.SBEprec % As above
                if exist('pow', 'var')
                    pow = round2(log10(abs(bakward)), 1, 'fix') + 1 ...
                                 - eval([obj.param '.SBEprec']);
                    bakward = round2(bakward, 10.^pow);
                else
                    bakward = round2(bakward, eval([obj.param '.SBEprec']));
                end
            end
            
            obj.outData.(obj.param) = bakward;
        end
        
        function out = filter(obj, in)
            out = in;
            B = 2*obj.A - 1;
            for i=2:length(in)
                out(i) = obj.A * (in(i) + in(i-1)) - B * out(i-1);
            end
        end
        
        function delete(obj) % Destructor
            % Here in case I need it
        end
    end
    
end